﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Dapper;
using DotnetSpider.DataFlow;
using DotnetSpider.DataFlow.Parser;
using DotnetSpider.DataFlow.Storage;
using DotnetSpider.Http;
using DotnetSpider.RequestSupplier;
using DotnetSpider.Scheduler.Component;
using DotnetSpider.Selector;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;

using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RabbitMQ.Client;
using Serilog;
using static DotnetSpider.Lawyee.Src.LawSpider;
using StringContent = DotnetSpider.Http.StringContent;

namespace DotnetSpider.Lawyee.Src
{
	public static class CommonHelper
	{

		/// <summary>
		/// 通用数理预处理
		/// </summary>
		/// <param name="context"></param>
		/// <returns></returns>
		public static string CommonParser(DataContext context)
		{
			string checkResult = string.Empty;
			string debugstring = string.Empty;
			try
			{
				var content = context.Response.ReadAsString().TrimStart();

				if (!string.IsNullOrEmpty(content) &&
					content.StartsWith("{") &&
					content.EndsWith("}"))
				{
					JObject jobj = JObject.Parse(content);
					if (jobj.Property("secretKey") != null &&
						jobj.Property("result") != null)
					{
						string secretKey = jobj["secretKey"].ToString();
						string result = jobj["result"].ToString();
						debugstring = "secretKey:" + secretKey + "；result：" + result;
						if (!string.IsNullOrEmpty(secretKey) && !string.IsNullOrEmpty(result))
						{
							if ((!result.StartsWith("{") && !result.EndsWith("}")) ||
								(!result.StartsWith("[") && !result.EndsWith("]")))
							{
								//需要解密处理 
								string iv = DateTime.Now.ToString("yyyyMMdd");

								string newResult = EncryptHelper.TripleDesDecryptorCBC(result, secretKey, iv).ToString();

								if ((!newResult.StartsWith("{") && !newResult.EndsWith("}")) &&
									(!newResult.StartsWith("[") && !newResult.EndsWith("]")))
								{
									Log.Logger.Warning("数据解密可能出现错误！");

								}
								else
								{

									checkResult = newResult;

								}


							}
							else
							{

								//无需解密处理
								checkResult = result;
							}

						}
						else
						{
							//无需解密处理
							checkResult = result;
						}

					}

				}


			}
			catch (Exception ex)
			{
				Log.Logger.Error(ex.ToString() + "data:" + debugstring);
			}

			return checkResult;
		}
		/// <summary>
		/// 重试请求
		/// </summary>
		/// <param name="context"></param>
		public static void RetryRequest(DataContext context)
		{
			string cookie = string.Empty;
			string url = string.Empty;
			try
			{
				TokenEntity tokenEntity = new TokenEntity();

				Tuple<string, string> tokenItem = tokenEntity.DonetTokenEx();

				cookie = tokenItem.Item1;
				url = tokenItem.Item2;

			}
			catch (Exception ex)
			{
				Log.Logger.Error(ex.ToString());
			}

			Request request = context.Request.Clone();
			request.RequestUri = new Uri(url);
			request.Cookie = cookie;
			context.AddFollowRequests(request);
		}


		/// <summary>
		/// 拆分成每天
		/// </summary>
		/// <param name="startDateString"></param>
		/// <param name="totalDays"></param>
		/// <returns></returns>
		public static Dictionary<string, int> SplitDateForDay(string startDateString, int totalDays)
		{
			DateTime startDate = Convert.ToDateTime(startDateString);   //开始日期
			Dictionary<string, int> splitDays = new Dictionary<string, int>();

			for (int i = 0; i <= totalDays; i++)
			{
				splitDays.Add(startDate.AddDays(i).ToString("yyyy-MM-dd"), 0);
			}
			return splitDays;
		}

		/// <summary>
		/// 从日期开始拆分请求，对分拆分
		/// </summary>
		/// <param name="startDateString"></param>
		/// <param name="totalDays"></param>
		/// <returns></returns>
		public static Dictionary<string, int> SplitDate(string startDateString, int totalDays)
		{

			int half = (int)totalDays / 2;  //商
			int rest = (int)totalDays % 2;  //余数



			int len = (int)totalDays / (half < 1 ? 1 : half) + (rest > 0 ? 1 : 0);   //循环次数 

			DateTime startDate = Convert.ToDateTime(startDateString);   //开始日期

			DateTime currentDate = startDate;                 //当前日期

			int subTime = half > 1 ? half : 1;                 //差值 

			Dictionary<string, int> splitDays = new Dictionary<string, int>();

			for (int i = 0; i < len; i++)
			{
				//当前日期
				string currentDateString = currentDate.ToString("yyyy-MM-dd");

				int timeSpanDays = (int)((currentDate.AddDays(subTime) - startDate).TotalDays);

				if ((int)timeSpanDays > totalDays)
				{

					int oneSpanDays = (int)((currentDate.AddDays(1) - startDate).TotalDays);

					if (oneSpanDays - totalDays == 0)
					{
						// Console.WriteLine(currentDateString + "\t" + currentDate.ToString("yyyy-MM-dd"));
						splitDays.Add(currentDateString, 1);
					}

					continue;
				}

				if (((int)timeSpanDays) == totalDays && rest > 0)
				{
					// Console.WriteLine(currentDateString + "\t" + currentDate.ToString("yyyy-MM-dd"));
					splitDays.Add(currentDateString, 1);

					currentDate = currentDate.AddDays(1);

				}
				else
				{

					currentDate = currentDate.AddDays(subTime);
					splitDays.Add(currentDateString, subTime);

					//Console.WriteLine(currentDateString + "\t" + currentDate.AddDays(-1).ToString("yyyy-MM-dd"));

				}

			}


			return splitDays;
		}


		public static void AddFYjson()
		{

			List<FYjson> fyjsons = JsonConvert.DeserializeObject<List<FYjson>>(File.ReadAllText(AppContext.BaseDirectory + "fy.json"));
			FYEntity FYEntity;
			FYEntity FYEntity1;
			FYEntity FYEntity2;
			FYEntity FYEntity3;
			foreach (var item in fyjsons)
			{
				FYEntity = new FYEntity() { id = item.id, code = item.code, name = item.name, parentid = item.parentid };
				if (FYEntity != null)
				{
					fylist.Add(FYEntity);
					foreach (var item1 in item.child)
					{
						FYEntity1 = new FYEntity() { id = item1.id, code = item1.code, name = item1.name, parentid = item1.parentid };
						if (FYEntity1 != null)
						{
							fylist.Add(FYEntity1);
							foreach (var item2 in item1.child)
							{
								FYEntity2 = new FYEntity() { id = item2.id, code = item2.code, name = item2.name, parentid = item2.parentid };
								if (FYEntity2 != null)
								{
									fylist.Add(FYEntity2);

									if (item2.child != null)
									{
										foreach (var item3 in item2.child)
										{
											FYEntity3 = new FYEntity() { id = item3.id, code = item3.code, name = item3.name, parentid = item3.parentid };
											if (FYEntity3 != null)
											{
												fylist.Add(FYEntity3);
											}
										}
									}

								}
							}
						}
					}
				}
			}
		}

	}
}
